﻿/*
 * Copyright (C) 2012, Jesus Requejo <jesus.requejo@gmail.com> 
 * Licensed under Microsoft Public License (Ms-PL)
 * http://www.microsoft.com/en-us/openness/licenses.aspx#MPL
*/

namespace Infrastructure {

   using System;
   using System.Collections.Generic;
   using System.Linq;
   using System.Text;
   using System.IO;

   public class FileSystemStorage : IStorageStrategy {

      public string StorageLocation { get; protected set; }
      private readonly string StorageFolderName = "LoaderService";
      private readonly string ApplicationListFileName = "ApplicationList.cfg"; 

      public FileSystemStorage() {
         string appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
         string storageFolder = Path.Combine(appDataFolder, StorageFolderName);

         StorageLocation = Path.Combine(storageFolder, ApplicationListFileName);

         CreateStorageFolderIfNeeded(storageFolder);
      }

      private void CreateStorageFolderIfNeeded(string storageFolder) {
         if (!Directory.Exists(storageFolder)) {
            Directory.CreateDirectory(storageFolder);
         }
      }

      public void SaveApplicationsList(IEnumerable<ApplicationEntry> appCollection) {
         SaveApplicationsListHelper(appCollection, StorageLocation);
      }

      private void SaveApplicationsListHelper(IEnumerable<ApplicationEntry> appCollection, string path) {
         FileStream fs = new FileStream(path, FileMode.Create);
         using (StreamWriter sw = new StreamWriter(fs)) {
            foreach (var app in appCollection) {
               var line = GenerateFileLine(app);
               sw.WriteLine(line);
            }
         }
      }

      public IList<ApplicationEntry> LoadApplicationsList() {
         return LoadApplicationsListHelper(StorageLocation);
      }

      private IList<ApplicationEntry> LoadApplicationsListHelper(string path) {
         try {
            FileStream fs = new FileStream(path, FileMode.Open);
            var appList = new List<ApplicationEntry>();
            using (StreamReader sr = new StreamReader(fs)) {

               string line;
               int lineNumber = 0;
               while ((line = sr.ReadLine()) != null) {
                  if (line.IndexOf("//") < 0 && !string.IsNullOrEmpty(line)) {
                     ApplicationEntry app = ParseLine(line, lineNumber++);
                     appList.Add(app);
                  }
               }
            }
            return appList;
         }
         catch (FileNotFoundException) {
            return new List<ApplicationEntry>();
         }
      }

      public string GenerateFileLine(ApplicationEntry app) {
         var line = String.Format("{0},{1},{2},{3}", app.Name, app.Path, app.Enabled, app.LaunchAtLogon);
         return line;
      }

      public ApplicationEntry ParseLine(string line, int lineNumber) {
         var fragments = line.Split(',');
         var name = fragments[0];
         var path = fragments[1];
         var enabled = Boolean.Parse(fragments[2]);
         var launchOnBoot = Boolean.Parse(fragments[3]);
         var app = new ApplicationEntry(lineNumber, name, path, enabled, launchOnBoot);
         return app;
      }
   }
}
